package com.jfinal.plugin.activerecord;

import com.jfinal.ext.kit.DateKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.sql.Spec;
import org.apache.commons.beanutils.ConvertUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 查询对象
 *
 * @author CHEN
 */
public class QueryObject {

    private Integer offset = 0;
    private Integer limit = 10;

    private Integer page;

    private String search;

    private Map<String, Object> params = new HashMap<>();
    private String sort;
    private String order = "asc";

    public Integer getOffset() {
        return offset;
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public Integer getPage() {
        return page != null ? page : (offset / limit) + 1;
    }

    public String getSort() {
        return sort;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    /**
     * 查询参数
     */
    public String getSearch() {
        return this.search;
    }

    public QueryObject addParam(String key, Object value) {
        fillParam(key, value);
        params.put(key, value);
        return this;
    }

    private void fillParam(String key, Object value) {
        switch (key) {
            case "page":
                this.page = Integer.valueOf(value.toString());
                break;
            case "limit":
                this.setLimit(Integer.valueOf(value.toString()));
                break;
            case "offset":
                this.setOffset(Integer.valueOf(value.toString()));
                break;
            case "search":
                this.search = (value.toString());
                break;
            case "sort":
                this.sort = (value.toString());
                break;
            case "order":
                this.order = (value.toString());
                break;
            default:
                break;
        }
    }


    public Spec toSpec() {
        Spec spec = new Spec();
        if ((this.getPage() != null && this.getPage() >= 0 && this.getLimit() != null && this.getLimit() > 0)) {
            spec.page(this.getPage(), this.getLimit());
        }
        spec.orderBy(this.getSort(), this.getOrder());
        return spec;
    }

    public <T> T getParam(String key) {
        return (T) params.get(key);
    }

    public <T> T getParam(String key, T defaultValue) {
        if (params.get(key) == null || params.get(key) == "") {
            return defaultValue;
        }
        return (T) params.get(key);
    }


    public Boolean getParamToBoolean(String key) {
        Object value = params.get(key);
        return (Boolean) ConvertUtils.convert(value, Boolean.class);
    }

    public String getParamToString(String key) {
        Object value = params.get(key);
        return (String) ConvertUtils.convert(value, String.class);
    }

    public Date getParamToDate(String key) {
        String value = getParam(key);
        if (value == null) {
            return null;
        }
        Date date = DateKit.toDate(value);
        return date;
    }

    public Date getParamToDate(String key, Date defaultValue) {
        Date date = getParamToDate(key);
        return date == null ? defaultValue : date;
    }

    public List<String> getParamToList(String key) {
        List<String> result = new ArrayList<>();
        Object values = getParam(key);
        if (values != null) {
            String[] arr = ((String) values).split(",");
            result.addAll(Arrays.asList(arr));
        }
        return result;
    }

    public Integer getParamToInteger(String key) {
        Object value = params.get(key);
        if (value == null) {
            return null;
        }
        if (StrKit.isBlank(String.valueOf(value))) {
            return null;
        }
        return (Integer) ConvertUtils.convert(value, Integer.class);
    }

    public boolean isParamNull(String key) {
        return getParam(key) == null;
    }

    public Map<String, Object> getParamMap() {
        return params;
    }

    public static void main(String[] args) throws ParseException {
        QueryObject queryObject = new QueryObject();
        queryObject.addParam("sort", "a").addParam("a", 1);
        String sql = queryObject.toSpec().and("a=?", 1).toSql();
        System.out.println("sql: " + sql);

        queryObject = new QueryObject();
        queryObject.addParam("date", "2013-12-1");
        queryObject.addParam("dateTime", "2013-12-1 12:00:00");

        Date date = queryObject.getParamToDate("date");
        System.out.println(date);

        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date date1 = sdf.parse("2013-12-1 12:22:33");
        System.out.println(date1);
    }


}